// DualView.m

#import "DualView.h"
#import "Controller.h"
#import <stdio.h>

@implementation DualView

- mouseDown: (NXEvent *)event
{
	NXPoint mouseLocation;
	
	mouseLocation = event->location;
	[self convertPoint:&mouseLocation fromView:nil];
	mouseLocation.x = xMin + mouseLocation.x / bounds.size.width * (xMax - xMin);
	mouseLocation.y = yMin + mouseLocation.y / bounds.size.height * (yMax - yMin);
	[controller addDual:mouseLocation];
	return self;
}

#define X(x) ((x - xMin) * sx)
#define Y(y) ((y - yMin) * sy)

- drawSelf:(const NXRect *)rects :(int)rectCount
{
	PointLine *primalPoint, *primalLine;
	int numberOfPrimalPoints, numberOfPrimalLines;
	int i;
	float sx = bounds.size.width / (xMax - xMin);
	float sy = bounds.size.height / (yMax - yMin);
	
	[super drawSelf:rects :rectCount];
		
	// draw dual lines (from primal points)
	// primal line y = ax - b <=> (a,b)
	[controller getPrimalPoints:&numberOfPrimalPoints :&primalPoint];
	for (i = 0; i < numberOfPrimalPoints; i++) {
		float x = xMin;
		float y = x * primalPoint[i].a - primalPoint[i].b;
		int dy = 0;		// used to adjust the position of the line label
		if (y < yMin && primalPoint[i].a) {
			y = yMin;
			x = (y + primalPoint[i].b) / primalPoint[i].a;
		} else if (y > yMax && primalPoint[i].a) {
			y = yMax;
			x = (y + primalPoint[i].b) / primalPoint[i].a;
			dy = -12;
		}
		NXSetColor(primalPoint[i].color);
		if ([showLabels state]) {
			PSmoveto(X(x), Y(y) + dy);
			PSshow(primalPoint[i].label);
		}
		PSmoveto(X(x), Y(y));
		PSlineto(X(xMax), Y(xMax * primalPoint[i].a - primalPoint[i].b));
		PSstroke();
	}

	// draw dual point (from primal lines)
	// primal point (a,b) <=> y = ax - b
	[controller getPrimalLines:&numberOfPrimalLines :&primalLine];
	for (i = 0; i < numberOfPrimalLines; i++) {
		NXSetColor(primalLine[i].color);
		if ([showLabels state]) {
			PSmoveto(X(primalLine[i].a), Y(-primalLine[i].b));
			PSshow(primalLine[i].label);
		}
		PSnewpath();
		PSarc(X(primalLine[i].a), Y(-primalLine[i].b), 2.0, 0.0, 360.0);
		PSfill();
	}
	
	return self;
}

@end
